﻿using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

using ICSharpCode.SharpZipLib.Zip.Compression;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Core;

namespace zipit
{
	class Program
	{
		static Regex[] ignoreFiles = null;
		static string startdir = null;

		static void Main(string[] args)
		{
			if (args.Length > 1)
			{
				string zipfilename = args[0];
				startdir = args[1];
				ignoreFiles = new Regex[args.Length - 2];
				for (int p = 0; p < args.Length - 2; p++)
					ignoreFiles[p] = new Regex("^" + args[p + 2].Replace("\\", "\\\\").Replace(".", "\\.").Replace("*", ".*?") + "$", RegexOptions.IgnoreCase);

				DirectoryInfo di = new DirectoryInfo(startdir);
				if (di.Exists)
				{
					startdir = di.FullName;
					using (FileStream fs = File.Create(zipfilename))
					using (ZipOutputStream zOut = new ZipOutputStream(fs))
						processDir(di, zOut);
				}
				else
					Console.WriteLine("Cannot find directory {0}", startdir);
			}
		}

		static void processDir(DirectoryInfo di, ZipOutputStream zOut)
		{
			foreach (DirectoryInfo cdi in di.GetDirectories())
				if(shouldbackup(cdi.Name))
					processDir(cdi, zOut);

			foreach (FileInfo cfi in di.GetFiles())
				if (shouldbackup(cfi.FullName))
				{
					string location = cfi.FullName.Substring(startdir.Length+1);
					zOut.PutNextEntry(new ZipEntry(location));
					int b;
					using (FileStream binDll = File.OpenRead(cfi.FullName))
						while ((b = binDll.ReadByte()) != -1)
							zOut.WriteByte((byte)b);
				}
		}

		static bool shouldbackup(string name)
		{
			foreach (Regex r in ignoreFiles)
				if (r.Match(name).Success)
					return false;
			return true;
		}
	}
}
